package Olivia.olivia3d.vo
{
	import Olivia.manager.ResManager;
	import Olivia.olivia3d.Olivia3D;
	import Olivia.olivia3d.shader.FragmentShader;
	import Olivia.olivia3d.shader.VertexShader;
	
	import com.adobe.utils.AGALMiniAssembler;
	
	import flash.display.Bitmap;
	import flash.display.Sprite;
	import flash.display.Stage3D;
	import flash.display3D.Context3D;
	import flash.display3D.Context3DProgramType;
	import flash.display3D.Context3DRenderMode;
	import flash.display3D.Context3DTextureFormat;
	import flash.display3D.Context3DTriangleFace;
	import flash.display3D.Program3D;
	import flash.display3D.textures.Texture;
	import flash.display3D.textures.TextureBase;
	import flash.events.ErrorEvent;
	import flash.events.Event;
	import flash.utils.Dictionary;

	public class Stage3DVo
	{		
		public var stage3D:Stage3D;
		public var context3D:Context3D;
		public var models:Array;
		public var lights:Array;
		public var pickPro3d:Program3D;
		public var pickPro3dAni:Program3D;
		
		private var _stgIdx:int;
		private var _main:Sprite;
				
		public function Stage3DVo()
		{
			
		}
		
		public function init(stgIdx:int):void
		{			
			models = new Array();
			lights = new Array();
			_stgIdx = stgIdx;
			_main = Olivia3D.ins.main;
			stage3D = _main.stage.stage3Ds[_stgIdx];
			if(!stage3D.context3D){
				stage3D.addEventListener(Event.CONTEXT3D_CREATE, contextCreated);
				stage3D.addEventListener(ErrorEvent.ERROR, contextCreationError);
				stage3D.requestContext3D(Context3DRenderMode.AUTO);
			}
		}
		
		[Embed(source="../default.jpg")]
		protected const DefaultTexture:Class;
		protected function contextCreated(event:Event):void
		{
			context3D = Stage3D(event.target).context3D;
			context3D.enableErrorChecking = true; //Can slow rendering - only turn on when developing/testing
			//this need deal, now this is...			
			context3D.configureBackBuffer(Olivia3D.ins.width, Olivia3D.ins.height, 4, true);
			context3D.setCulling(Context3DTriangleFace.FRONT);
			//pick program3D
			createPickPro3d();
			//default texture
			var bm:Bitmap = new DefaultTexture();
			var texture:Texture = context3D.createTexture(bm.bitmapData.width,
				bm.bitmapData.height,
				Context3DTextureFormat.BGRA,
				true);
			texture.uploadFromBitmapData(bm.bitmapData);
			tsList["default"] = texture;
			trace("3D driver: " + context3D.driverInfo);
		}
		
		protected function createPickPro3d():void
		{
			pickPro3d = context3D.createProgram();
			pickPro3dAni = context3D.createProgram();
			
			var vsAgal:AGALMiniAssembler = new AGALMiniAssembler();
			var fsAgal:AGALMiniAssembler = new AGALMiniAssembler();
			
			//baseType
			vsAgal.assemble(Context3DProgramType.VERTEX,VertexShader.pickVsAgal(),false);
			fsAgal.assemble(Context3DProgramType.FRAGMENT,FragmentShader.pickFsAgal(),false);
			pickPro3d.upload(vsAgal.agalcode,fsAgal.agalcode);
			
			//aniType
			vsAgal.assemble(Context3DProgramType.VERTEX,VertexShader.pickVsAgalAni(),false);
			fsAgal.assemble(Context3DProgramType.FRAGMENT,FragmentShader.pickFsAgal(),false);
			pickPro3dAni.upload(vsAgal.agalcode,fsAgal.agalcode);
		}
		
		protected function contextCreationError(error:ErrorEvent):void
		{
			trace(error.errorID + ": " + error.text);
		}
		
		public function updateWH(event:Event):void
		{
			context3D.configureBackBuffer(Olivia3D.ins.width, Olivia3D.ins.height, 4, true);
		}
		
		/**
		 * 设置agal 
		 * @param vs
		 * @param fs
		 * 
		 */		
		public function setAgal(program3D:Program3D):void
		{
			context3D.setProgram(program3D);
		}
		
		/**
		 * 清理buffer&textrue 
		 * @param context3D
		 * 
		 */		
		public function clearBufferAndTexture():void
		{
			// TODO Auto Generated method stub
			context3D.setVertexBufferAt(0, null);	//va0 is vertex	
			context3D.setVertexBufferAt(1, null);	//va1 is normals
			context3D.setVertexBufferAt(2, null);	//va2 is uv
			context3D.setVertexBufferAt(3, null);	//va3 is bornid
			context3D.setTextureAt(0, null);
			context3D.setTextureAt(1, null);	
		}
				
		protected var tsList:Dictionary = new Dictionary();
		public function getTexture(url:String):TextureBase
		{
			var textureName:String = url;
			textureName = textureName.replace(".\\","");
			textureName = textureName.replace("tga","jpg");
			if(!tsList.hasOwnProperty(textureName))
			{
				ResManager.load(textureName,
					function(res:Bitmap,resUrl:String):void
					{
						var texture:Texture = context3D.createTexture(res.bitmapData.width,
							res.bitmapData.height,
							Context3DTextureFormat.BGRA,
							false);
						texture.uploadFromBitmapData(res.bitmapData);
						tsList[resUrl] = texture;
					},textureName);
				return tsList["default"];
			}
			else
			{
				return tsList[textureName];
			}
		}
	}
}